/*
* common.cpp - This file is the part of the wp-notifier.(code name "luan luan")
* Copyright (C) 2010 Dean Lee <deanlee3@gmail.com>, http://www.deanlee.cn
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program.  If not, see <http://www.gnu.org/licenses/>.
* 
* Acknowledgements:
*   <> Many thanks to all of you, who have encouraged me to update my articles
*     and code, and who sent in bug reports and fixes.
* 
*/
#include <windows.h>
#include <QDir>
#include <QApplication>
#include <QWidget>
#include <QDateTime>
#include "common.h"

QString homeDir()
{
	// Try the environment override first
	/*#if defined(Q_WS_X11)
	QDir proghome(QDir::homeDirPath() + "/.psi");
	if(!proghome.exists()) {
	QDir home = QDir::home();
	home.mkdir(".psi");
	chmod(QFile::encodeName(proghome.path()), 0700);
	}
	return proghome.path();
	#elif defined(Q_WS_WIN)
	//QString base = QDir::currentPath();
	QString base = QCoreApplication::applicationDirPath();//QDir::currentPath();
	// no trailing slash
	if(base.at(base.length()-1) == '/')
	base.truncate(base.length()-1);

	QDir proghome(base + "/Data");
	if(!proghome.exists()) {
	QDir home(base);
	home.mkdir("Data");
	}

	return proghome.path();
	#elif defined(Q_WS_MAC)
	QDir proghome(QDir::homeDirPath() + "/.psi");
	if(!proghome.exists()) {
	QDir home = QDir::home();
	home.mkdir(".psi");
	chmod(QFile::encodeName(proghome.path()), 0700);
	}

	return proghome.path();
	#endif*/
	// Try the environment override first
	char *p = getenv("EQDATADIR");
	if(p)
		return p;

#if defined(Q_WS_X11)
	QDir proghome(QDir::homeDirPath() + "/.wp-notifier");
	if(!proghome.exists()) {
		QDir home = QDir::home();
		home.mkdir(".wp-notifier");
		chmod(QFile::encodeName(proghome.path()), 0700);
	}
	return proghome.path();
#elif defined(Q_WS_WIN)
	QString base;

	// Windows 9x
	if(QDir::homePath() == QDir::rootPath())
		base = ".";
	// Windows NT/2K/XP variant
	else
		base = QDir::homePath();

	// no trailing slash
	if(base.at(base.length()-1) == '/')
		base.truncate(base.length()-1);

	QDir proghome(base + "/wp-notifier");
	if(!proghome.exists()) {
		QDir home(base);
		home.mkdir("wp-notifier");
	}

	return proghome.path();
#elif defined(Q_WS_MAC)
	QDir proghome(QDir::homeDirPath() + "/.wp-notifier");
	if(!proghome.exists()) {
		QDir home = QDir::home();
		home.mkdir(".wp-notifier");
		chmod(QFile::encodeName(proghome.path()), 0700);
	}

	return proghome.path();
#endif
}

void setStartup(bool bStartup)
{
	HKEY hKey = NULL;
	DWORD dwDisp = 0;
	if ( ERROR_SUCCESS == ::RegCreateKeyExA(HKEY_CURRENT_USER,"Software\\Microsoft\\Windows\\CurrentVersion\\Run",
		NULL, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, &dwDisp)) {
		if (bStartup) {
			QString appPath = "\"" + qApp->applicationFilePath() + "\"";
			appPath.replace("/", "\\");
			appPath += " /background";
			if (ERROR_SUCCESS != ::RegSetValueExA(hKey, "wpnotifier", 0, REG_SZ,
				(BYTE*)qPrintable(appPath), appPath.length() + 1)) {
			}
		}
		else {
			if (ERROR_SUCCESS != ::RegDeleteValueA(hKey, "wpnotifier")) {
			}
		}
		::RegCloseKey(hKey);
	}
}

void bringToFront(QWidget *widget)
{
	Q_ASSERT(widget);
	QWidget* w = widget->window();

#ifdef Q_WS_X11
	// If we're not on the current desktop, do the hide/show trick
	long dsk, curr_dsk;
	Window win = w->winId();
	if(desktopOfWindow(&win, &dsk) && currentDesktop(&curr_dsk)) {
		//qDebug() << "bringToFront current desktop=" << curr_dsk << " windowDesktop=" << dsk;
		if((dsk != curr_dsk) && (dsk != -1)) {  // second condition for sticky windows
			w->hide();
		}
	}

	// FIXME: multi-desktop hacks for Win and Mac required
#endif

	if(w->isMaximized())
		w->showMaximized();
	else
		w->showNormal();

	//if(grabFocus)
	//	w->setActiveWindow();
	w->raise();
	w->activateWindow();
}

QString dateDiffString(const QDateTime& d)
{
	QDateTime now = QDateTime::currentDateTime();
	QString dateDiff;
	int diff = d.secsTo(now) / 60.0;
	if (diff < 60) {
		dateDiff = QObject::tr("%1 minutes ago").arg(diff ? diff : 1);
	}
	else {
		diff /= 60;
		if (diff < 24) {
			dateDiff= QObject::tr("%1 hours ago").arg(diff);
		}
		else {
			diff /= 24;
			if (diff < 30) {
				dateDiff = QObject::tr("%1 days ago").arg(diff);
			}
			else {
				diff /= 30;
				dateDiff = QObject::tr("%1 months ago").arg(diff);
			}
		}

	}
	return dateDiff;
}

QString escapedString(const QString &s, bool escapeWhitespace)
{
	QString escaped;
	escaped.reserve(s.size());
	for ( int i = 0; i < s.size(); ++i ) {
		QChar c = s.at(i);
		if (c.unicode() == '<' )
			escaped.append(QLatin1String("&lt;"));
		else if (c.unicode() == '>' )
			escaped.append(QLatin1String("&gt;"));
		else if (c.unicode() == '&' )
			escaped.append(QLatin1String("&amp;"));
		else if (c.unicode() == '\"' )
			escaped.append(QLatin1String("&quot;"));
		else if (escapeWhitespace && c.isSpace()) {
			if (c.unicode() == '\n')
				escaped.append(QLatin1String("&#10;"));
			else if (c.unicode() == '\r')
				escaped.append(QLatin1String("&#13;"));
			else if (c.unicode() == '\t')
				escaped.append(QLatin1String("&#9;"));
			else
				escaped += c;
		} else {
			escaped += QChar(c);
		}
	}
	return escaped;
}


QDomElement findSubTag(const QDomElement &e, const QString &name, bool *found)
{
	if(found)
		*found = false;

	for(QDomNode n = e.firstChild(); !n.isNull(); n = n.nextSibling()) {
		QDomElement i = n.toElement();
		if(i.isNull())
			continue;
		if(i.tagName() == name) {
			if(found)
				*found = true;
			return i;
		}
	}

	QDomElement tmp;
	return tmp;
}

QString tagContent(const QDomElement &e)
{
	// look for some tag content
	for(QDomNode n = e.firstChild(); !n.isNull(); n = n.nextSibling()) {
		QDomText i = n.toText();
		if(i.isNull())
			continue;
		return i.data();
	}

	return "";
}

void readEntry(const QDomElement &e, const QString &name, QString *v)
{
	bool found = FALSE;
	QDomElement tag = findSubTag(e, name, &found);
	if(!found)
		return;
	*v = tagContent(tag);
}

void readNumEntry(const QDomElement &e, const QString &name, int *v)
{
	bool found = FALSE;
	QDomElement tag = findSubTag(e, name, &found);
	if(!found)
		return;
	*v = tagContent(tag).toInt();
}

void readBoolEntry(const QDomElement &e, const QString &name, bool *v)
{
	bool found = FALSE;
	QDomElement tag = findSubTag(e, name, &found);
	if(!found)
		return;
	*v = (tagContent(tag) == "true") ? TRUE: FALSE;
}

void readSizeEntry(const QDomElement &e, const QString &name, QSize *v)
{
	bool found = FALSE;
	QDomElement tag = findSubTag(e, name, &found);
	if(!found)
		return;
	QStringList list = tagContent(tag).split(',');
	if(list.count() != 2)
		return;
	QSize s;
	s.setWidth(list[0].toInt());
	s.setHeight(list[1].toInt());
	*v = s;
}

void readRectEntry(const QDomElement &e, const QString &name, QRect *v)
{
	bool found = FALSE;
	QDomElement tag = findSubTag(e, name, &found);
	if(!found)
		return;
	QStringList list = tagContent(tag).split(',');
	if(list.count() != 4)
		return;
	QRect r;
	r.setX(list[0].toInt());
	r.setY(list[1].toInt());
	r.setWidth(list[2].toInt());
	r.setHeight(list[3].toInt());
	*v = r;
}

QDomElement textTag(QDomDocument &doc, const QString &name, QSize &s)
{
	QString str;
	str.sprintf("%d,%d", s.width(), s.height());

	QDomElement tag = doc.createElement(name);
	QDomText text = doc.createTextNode(str);
	tag.appendChild(text);

	return tag;
}


QDomElement textTag(QDomDocument &doc, const QString &name, QRect &r)
{
	QString str;
	str.sprintf("%d,%d,%d,%d", r.x(), r.y(), r.width(), r.height());

	QDomElement tag = doc.createElement(name);
	QDomText text = doc.createTextNode(str);
	tag.appendChild(text);

	return tag;
}
QDomElement textTag(QDomDocument &doc, const QString &name, const QString &content)
{
	QDomElement tag = doc.createElement(name);
	QDomText text = doc.createTextNode(content);
	tag.appendChild(text);

	return tag;
}